﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DotHandler
{
    public class Lista<T> : Colecao<T>
    {
        #region Construtor
        public Lista(uint size)
            : base(size)
        {
            this._index = new int[1];
            this._index[0] = -1;
        }
        #endregion

        #region Métodos
        public void Add(dynamic o, bool identity=true)
        {
            if (!this.IsFull())
            {
                _index[0] += 1;
                this._storage[_index[0]] = o;
                if (identity)
                {
                    o.Identity(this.identity);
                    this.identity += 1;
                }
            }
            else
            {
                throw new NullReferenceException();
            }
            this.Sort();
        }

        public void Add(Boolean multiple, params dynamic[] o)
        {
            foreach (var item in o)
            {
                this.Add(item);
            }
        }

        public dynamic Remove(int pos)
        {
            if (!IsEmpty())
            {
                int steps = (int)(_index[0] - pos);
                if (steps < 0 || pos < 0)
                {
                    throw new Exception("Wrong position assignment");
                }
                uint step = 0;
                uint position = (uint)pos;
                dynamic exItem = _storage[pos];
                while (step < steps)
                {
                    _storage[position] = _storage[position + 1];
                    position += 1;
                    step += 1;
                }
                _index[0] -= 1;
                return exItem;
            }
            return null;
        }

        public dynamic[] Remove(Boolean multiple, int qtd)
        {
            if (qtd <= Quantity)
            {
                dynamic[] retorno = new dynamic[qtd];
                for (var i = 0; i < qtd; i += 1)
                {
                    retorno[i] = Remove(Index);
                }
                return retorno;
            }
            throw new NullReferenceException();
        }

        public void Update(uint pos, dynamic o)
        {
            if (pos <= this._index[0] && !this.IsEmpty())
            {
                this._storage[pos] = o;
            }
        }

        public override int Quantity
        {
            get { return this.Index + 1; }
        }

        public override Boolean IsFull()
        {
            return !(Index < Size - 1);
        }

        public override Boolean IsEmpty()
        {
            return (Index == -1);
        }

        public override int Index
        {
            get { return this._index[0]; }
        }

        public override void Destroy()
        {
            this._index[0] = -1;
            this._storage = new dynamic[Size];
        }

        public override void Each(Func<dynamic, bool> handler)
        {
            for (var i = 0; i <= this.Index; i += 1)
            {
                if (handler(this._storage[i]) == false)
                {
                    break;
                };
            }
        }
        #endregion

    }
}
